// logyou.de landing page → ERP lead intake.
// Same target as the FluentForm webhook (fulfillment-leads.post.ts): creates an
// AD_User sales lead via the iDempiere service token, with the same email dedupe.
//
// Two callers / auth paths:
//   1. Server-to-server: `Authorization: Bearer <LANDING_LEAD_TOKEN>`
//      (runtimeConfig.api.landingLeadToken), timing-safe compare.
//   2. Browser: the landing form POSTs directly from logyou.de — allowed when the
//      Origin header matches the allowlist (see server/utils/landingLeadCors.ts;
//      preflight answered by landing-leads.options.ts). The browser path is
//      guarded by a honeypot field `_hp` and a per-IP rate limit.
//   Anything else → 403.
//
// After lead creation (and on dedupe, since a returning prospect is still a fresh
// inquiry) a plain-text notification mail goes to info@logyou.de via the local
// MTA — same transport as server/api/contact/send.post.ts. Mail failure never
// fails the request.
//
// Payload (JSON): { name, company, email, phone, brand_url, volume, weight, items,
//                   integrations: string[], cta_source, locale, _hp? }
import { createHash, timingSafeEqual } from 'node:crypto'
import { getRequestIP } from 'h3'
import nodemailer from 'nodemailer'
import { string } from 'alga-js'
import errorHandlingHelper from '../../utils/errorHandlingHelper'
import { applyLandingLeadCors } from '../../utils/landingLeadCors'

// Hash both sides so timingSafeEqual always gets equal-length buffers.
const safeEqual = (a: string, b: string): boolean =>
    timingSafeEqual(createHash('sha256').update(a).digest(), createHash('sha256').update(b).digest())

// --- Per-IP rate limit for the browser path: 1 request / 30s / IP. ---
// Per-process Map — PM2 runs 2 cluster instances, so the effective allowed rate
// doubles (same accepted caveat as authCooldown/notificationBus).
const lastRequestAt = new Map<string, number>()
const RATE_WINDOW_MS = 30_000
const SWEEP_THRESHOLD = 500 // lazy cleanup to bound memory

const rateLimited = (ip: string): boolean => {
    const now = Date.now()
    if (lastRequestAt.size > SWEEP_THRESHOLD) {
        for (const [k, t] of lastRequestAt) {
            if (now - t > RATE_WINDOW_MS) lastRequestAt.delete(k)
        }
    }
    const last = lastRequestAt.get(ip)
    if (last && now - last < RATE_WINDOW_MS) return true
    lastRequestAt.set(ip, now)
    return false
}

// Notification target is intentionally hard-coded, never taken from the
// request body — the landing page has no legitimate reason to redirect where
// its own lead notifications go.
const LANDING_LEAD_NOTIFY_TO = 'info@logyou.de'

const escapeHtml = (s: string): string =>
    String(s).replace(/[&<>"']/g, (c) => ({ '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c] as string))

// Prefixes a scheme onto bare domains ("younex.de", "www.younex.de") so the
// mail's link is actually clickable — mirrors the landing form's own
// normalization (ContactModal.vue normalizedBrandUrl()).
const normalizeUrl = (u: string): string => (/^https?:\/\//i.test(u) ? u : `https://${u}`)

// HTML + plain-text notification to the sales inbox (local MTA, like
// contact/send.post.ts). Phone/URL/email are rendered as tel:/https:/mailto:
// links so the recipient can tap-to-call or open the brand site directly.
const sendNotificationMail = async (body: any, integrations: string[], duplicate: boolean) => {
    const transporter = nodemailer.createTransport({
        host: 'localhost', port: 25, secure: false, tls: { rejectUnauthorized: false }
    })

    const name = String(body.name || '').trim()
    const company = String(body.company || '').trim()
    const brandUrl = String(body.brand_url || '').trim()
    const email = String(body.email || '').trim()
    const phone = String(body.phone || '').trim()
    const brandUrlHref = brandUrl ? normalizeUrl(brandUrl) : ''
    const phoneHref = phone ? `tel:${phone.replace(/[^\d+]/g, '')}` : ''

    const rows: Array<[string, string]> = [
        ['Name', name ? escapeHtml(name) : '–'],
        ['Firma', company ? escapeHtml(company) : '–'],
        ['Brand-URL', brandUrlHref ? `<a href="${escapeHtml(brandUrlHref)}" target="_blank" rel="noopener">${escapeHtml(brandUrl)}</a>` : '–'],
        ['E-Mail', email ? `<a href="mailto:${escapeHtml(email)}">${escapeHtml(email)}</a>` : '–'],
        ['Telefon', phoneHref ? `<a href="${escapeHtml(phoneHref)}">${escapeHtml(phone)}</a>` : '–'],
        ['Sendungen/Monat', body.volume ? escapeHtml(body.volume) : '–'],
        ['Gewicht', body.weight ? escapeHtml(body.weight) : '–'],
        ['Items/Auftrag', body.items ? escapeHtml(body.items) : '–'],
        ['Systeme', integrations.length ? escapeHtml(integrations.join(', ')) : '–'],
        ['CTA-Quelle', body.cta_source ? escapeHtml(body.cta_source) : '–'],
        ['Sprache', body.locale ? escapeHtml(body.locale) : '–']
    ]

    const htmlRows = rows.map(([label, value]) => `
        <tr>
            <td style="padding:8px 16px 8px 0;color:#64748b;font-size:13px;white-space:nowrap;vertical-align:top;">${escapeHtml(label)}</td>
            <td style="padding:8px 0;color:#0f172a;font-size:14px;vertical-align:top;">${value}</td>
        </tr>`).join('')

    const html = `
<div style="font-family:-apple-system,Segoe UI,Roboto,Arial,sans-serif;max-width:560px;margin:0 auto;">
    <div style="background:#F05A28;padding:20px 24px;border-radius:12px 12px 0 0;">
        <span style="color:#fff;font-size:12px;font-weight:700;letter-spacing:0.06em;text-transform:uppercase;">Neue Anfrage · logyou.de</span>
        <h1 style="color:#fff;font-size:20px;margin:6px 0 0;">${escapeHtml(company || name || email)}</h1>
    </div>
    ${duplicate ? '<div style="background:#fef3c7;color:#92400e;font-size:13px;font-weight:600;padding:10px 24px;">⚠ Bereits als Lead vorhanden (Duplikat) — trotzdem eine frische Anfrage.</div>' : ''}
    <table style="width:100%;border-collapse:collapse;background:#fff;border:1px solid #e2e8f0;border-top:none;border-radius:0 0 12px 12px;padding:8px 24px;">
        ${htmlRows}
    </table>
    <p style="color:#94a3b8;font-size:11px;margin:16px 4px;">Eingegangen über logyou.de · Antwort direkt per Reply-To an den Interessenten.</p>
</div>`

    const textLines = [
        'Name: ' + (name || '-'),
        'Firma: ' + (company || '-'),
        'Brand-URL: ' + (brandUrl || '-'),
        'E-Mail: ' + (email || '-'),
        'Telefon: ' + (phone || '-'),
        'Sendungen/Monat: ' + (body.volume || '-'),
        'Gewicht: ' + (body.weight || '-'),
        'Items/Auftrag: ' + (body.items || '-'),
        'Systeme: ' + (integrations.length ? integrations.join(', ') : '-'),
        'CTA-Quelle: ' + (body.cta_source || '-'),
        'Sprache: ' + (body.locale || '-')
    ]
    if (duplicate) textLines.push('', 'Bereits als Lead vorhanden (Duplikat)')

    const mail: any = {
        from: 'no-reply@logyou.de',
        to: LANDING_LEAD_NOTIFY_TO,
        subject: `[LogShip Anfrage] ${company || name || email}`,
        text: textLines.join('\n'),
        html
    }
    if (email) mail.replyTo = email
    await transporter.sendMail(mail)
}

export default defineEventHandler(async (event) => {
    let data: any = {}

    try {
        const config = useRuntimeConfig()
        const originAllowed = applyLandingLeadCors(event)

        // --- Auth: valid Bearer token (server-to-server) OR allowlisted Origin (browser) ---
        const expected = config.api.landingLeadToken
        const auth = getHeader(event, 'authorization') || ''
        const provided = auth.startsWith('Bearer ') ? auth.slice(7) : ''
        const serverPath = Boolean(expected && provided && safeEqual(provided, expected))
        if (!serverPath && !originAllowed) {
            setResponseStatus(event, 403)
            return { ok: false, status: 403, message: 'Forbidden' }
        }

        // --- Abuse protection for the public browser path ---
        if (!serverPath) {
            const ip = getRequestIP(event, { xForwardedFor: true }) ?? 'unknown'
            if (rateLimited(ip)) {
                setResponseStatus(event, 429)
                return { ok: false, error: 'too_many' }
            }
        }

        const token = config.api.idempieretoken
        const body = await readBody(event)

        // Honeypot: bots fill the hidden field → pretend success, do nothing.
        if (typeof body?._hp === 'string' && body._hp.trim() !== '') {
            return { ok: true }
        }

        // Validate required fields
        if (!body?.email) {
            setResponseStatus(event, 400)
            return { ok: false, status: 400, message: 'Email is required' }
        }

        // Client/Org come from the server env only (never from the public payload)
        const clientId = process.env.DEFAULT_CLIENT_ID || 1000000
        const orgId = process.env.DEFAULT_ORG_ID || 1000000

        const integrations = (Array.isArray(body.integrations) ? body.integrations : []).filter(Boolean)

        // Check if a lead/user already exists with this email (same dedupe as fulfillment-leads)
        const res: any = await $fetch(config.api.url+`/models/ad_user?$filter=${string.urlEncode("eMail eq '"+body.email+"'")}`, {
            method: 'GET',
            headers: {
                'Content-Type': 'application/json',
                Accept: 'application/json',
                Authorization: 'Bearer '+token
            },
        })

        if(Number(res?.records?.length ?? 0) >= 1) {
            // Duplicate is not an error for the landing — but a returning prospect
            // is still a fresh inquiry, so the notification mail goes out anyway.
            try {
                await sendNotificationMail(body, integrations, true)
            } catch (mailErr: any) {
                console.error('[landing-leads] notification mail failed (duplicate):', mailErr?.message ?? mailErr)
            }
            data = {
                ok: true,
                duplicate: true,
                status: 409,
                message: 'Lead already exists with this email',
                email: body.email
            }
            return data
        }

        // Qualification data has no own AD_User fields → readable text in Comments
        const comments = [
            body.company ? 'Firma: ' + body.company : '',
            body.volume ? 'Paketmenge: ' + body.volume : '',
            body.weight ? 'Paketgewicht: ' + body.weight : '',
            body.items ? 'Artikel: ' + body.items : '',
            integrations.length ? 'Shopsystem: ' + integrations.join(', ') : '',
            body.cta_source ? 'CTA: ' + body.cta_source : '',
            body.locale ? 'Sprache: ' + body.locale : ''
        ].filter(Boolean).join(' | ')

        // Create new lead
        const createRes: any = await $fetch(config.api.url+'/models/ad_user', {
            method: 'POST',
            headers: {
                'Content-Type': 'application/json',
                Accept: 'application/json',
                Authorization: 'Bearer '+token
            },
            body: {
                AD_Client_ID: {
                    id: clientId,
                    tableName: 'AD_Client'
                },
                AD_Org_ID: {
                    id: orgId,
                    tableName: 'AD_Org'
                },
                isActive: true,
                name: (body.name || '').trim() || body.email,
                description: 'Shopsystem: ' + integrations.join(', '),
                eMail: body.email,
                isFullBPAccess: false,
                isInPayroll: false,
                isSalesLead: true,
                isLocked: false,
                isNoPasswordReset: false,
                isExpired: false,
                isAddMailTextAutomatically: false,
                isNoExpire: true,
                isSupportUser: false,
                isShipTo: true,
                isBillTo: false,
                isVendorLead: true,
                eMailUser: body.email,
                phone: body.phone,
                URL: body.brand_url,
                comments: comments,
                NotificationType: {
                    id: 'X'
                },
                LeadSource: {
                    id: 'EC'
                },
                LeadStatus: {
                    id: 'N'
                },
                LeadSourceDescription: 'logyou.de Landingpage' + (body.cta_source ? ' – ' + body.cta_source : ''),
                tableName: 'AD_User'
            }
        })

        // Success response
        if(createRes && createRes.id) {
            try {
                await sendNotificationMail(body, integrations, false)
            } catch (mailErr: any) {
                console.error('[landing-leads] notification mail failed:', mailErr?.message ?? mailErr)
            }
            data = {
                ok: true,
                status: 201,
                message: 'Lead created successfully',
                id: createRes.id,
                email: body.email
            }
        } else {
            setResponseStatus(event, 500)
            data = {
                ok: false,
                status: 500,
                message: 'Failed to create lead - no ID returned',
                email: body.email
            }
        }

    } catch(err: any) {
        console.error('[landing-leads] lead creation failed:', err?.data ?? err?.message ?? err)
        setResponseStatus(event, 500)
        data = errorHandlingHelper(err?.data ?? err)
        data.ok = false
        data.message = data.message || 'Internal server error while creating lead'
    }

    return data
})
